//#include "common.h"
//
//#define	USER_INPUT_INTERVAL		100
//ITetris* g_pTetris= NULL;
//
//void UserInputThreadProc()
//{
//	if(g_pTetris)
//	{
//		BOOL bPaused = FALSE;
//		char ch;
//		while(1)
//		{
//			ch = GetInput();
//			switch(ch)
//			{
//			case 'a':
//			case 'A':
//				g_pTetris->Left();
//				break;
//			case 's':
//			case 'S':
//				g_pTetris->Drop();
//				break;
//			case 'd':
//			case 'D':
//				g_pTetris->Right();
//				break;
//			case 'w':
//			case 'W':
//				g_pTetris->Rotate();
//				break;
//			case '2':
//				g_pTetris->Down();
//				break;
//			}
//			sleep(USER_INPUT_INTERVAL);
//		}
//	}
//}


//#include <iostream>
//
//int main(int argc, char* argv[])
//{
//	//printf("\033[2J");
//	//printf("\033[33mHello\n");
//
//	//g_pTetris = CreateTetris();
//
//	std::cout << "hello" << std::endl;
//
//	return	0;
//}


#include <iostream>
#include <string>
#include <boost/thread.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/locks.hpp>
#include <stdio.h>
#include <termios.h>
#include <unistd.h>
#include <assert.h>
#include "itetris.h"
#include "lnx_console_ui.h"
using namespace std;

int getch()
{
	int c = 0;
	struct termios org_opts, new_opts;
	int res = 0;
	res = tcgetattr(STDIN_FILENO, &org_opts);
	assert(res == 0);
	memcpy(&new_opts, &org_opts, sizeof(new_opts));
	new_opts.c_lflag &= ~(ICANON | ECHO | ECHOE | ECHOK | ECHONL | ECHOPRT | ECHOKE | ICRNL);
	tcsetattr(STDIN_FILENO, TCSANOW, &new_opts);
	c = getchar();
	res = tcsetattr(STDIN_FILENO, TCSANOW, &org_opts);assert(res == 0);
	return c;
}


bool bExit = false;
bool bPausePrint = false;
boost::mutex g_mutex;
int row = 0, col = 0;
ITetrisUI* pTetrisUI = NULL;

#define WIDTH	10
#define HEIGHT	20

void move_left()
{
	if(pTetrisUI)
	{
		if(col - 1 >= 0)
		{
			pTetrisUI->UpdateSinkPixel(row, col, 0);
			--col;
			pTetrisUI->UpdateSinkPixel(row, col, 1);
		}
	}
}

void move_right()
{
	if(pTetrisUI)
	{
		if(col + 1 <= WIDTH - 1)
		{
			pTetrisUI->UpdateSinkPixel(row, col, 0);
			++col;
			pTetrisUI->UpdateSinkPixel(row, col, 1);
		}
	}
}

void move_down()
{
	if(pTetrisUI)
	{
		pTetrisUI->UpdateSinkPixel(row, col, 0);
		if(row + 1 <= HEIGHT - 1)
		{
			++row;
		}
		else
		{
			row = 0;
		}
		pTetrisUI->UpdateSinkPixel(row, col, 1);
	}
}

void auto_down()
{
	int i = 0;
	while(!bExit)
	{
		g_mutex.lock();

		usleep(500000);
// 		cout << i << endl;
// 		i = (i + 1) % 100;
// 		cout << 'a';
		move_down();

		g_mutex.unlock();
	}
}

void input()
{
	char ch = ' ';
	while(1)
	{
		ch = getch();
// 		cout << ch << endl;
		if(ch == 'q' || ch == 'Q')
		{
			bExit = true;
			break;
		}
		else if(ch == 'p' || ch == 'P')
		{
			bPausePrint = !bPausePrint;
			if(bPausePrint)
			{
				g_mutex.lock();
			}
			else
			{
				g_mutex.unlock();
			}
		}
		else if(ch == 'a' || ch == 'A')
		{
			if(!bPausePrint)
			{
				move_left();
			}
		}
		else if(ch == 'd' || ch == 'D')
		{
			if(!bPausePrint)
			{
				move_right();
			}
		}
		else if(ch == 's' || ch == 'S')
		{
			if(!bPausePrint)
			{
				move_down();
			}
		}
	}
}

int main(int argc, char* argv[])
{
	printf("\033[2J");
	printf("\033[?25l");
	fflush(stdout);
	pTetrisUI = new CLnxConsoleUI();
	boost::thread t1(&auto_down);
	boost::thread t2(&input);
	t1.join();
	t2.join();
	delete pTetrisUI;

	printf("\033[2J");
	return	0;
}
	//printf("\033[2J");
	//printf("\033[33mHello\n");
